from PyQt5.QtWidgets import QDialog
import time
import cv2
import numpy as np
import math
import Processor.Converter as Converter
import Utility.LUT as LUT
from Plugin.ColorLookup.ColorLookup_design import Ui_ColorLookupController


class ColorLookupController(QDialog, Ui_ColorLookupController):
    layer = None  # 图层
    mat = None  # 原始Mat 数据
    colorTable = None   # 颜色表

    def __init__(self, parent, mat=None):
        super().__init__(parent)
        self.setupUi(self)
        self.mat = mat
        self.colorTable = ColorTable
        self.initUI(parent)

    def reject(self):
        """
        取消操作
        :return:
        """
        image = Converter.Numpy2QImage(self.mat)
        self.layer.updatePixmap(image)
        QDialog.reject(self)

    def initUI(self, parent):
        self.setWindowTitle('颜色找查表')
        self.panel_arg.hide()
        # 定位
        self.resize(160, 160)
        pos = parent.geometry()
        self.move((pos.width() - self.width()) / 2, (pos.height() - self.height()) / 2)
        # 添加颜色表
        for i in range(0, len(self.colorTable)):
            self.comboBox_colorTable.addItem(self.colorTable[i]['name'])
        #           信号
        # 对话框确定
        self.DialogButtonBox.accepted.connect(self.accept)
        self.DialogButtonBox.rejected.connect(self.reject)
        # 参数
        self.comboBox_colorTable.currentIndexChanged.connect(self.__comboBox_colorTable_change_slot)

    def __comboBox_colorTable_change_slot(self):
            self.updateSlot()

    def updateSlot(self):
        index = self.comboBox_colorTable.currentIndex()
        pro = self.colorTable[index].get('processor', None)
        if pro:
            pro(self.mat)


Window = None  # 主窗体
ColorTable = {}  # 颜色表
Layer = None    # 图层


def init(window):
    """
    初始化
    :param window: 主窗体
    :return:
    """
    global Window
    Window = window
    __menu()  # 创建菜单栏
    __initColorTable()  # 颜色表


def __menu():
    """
    将插件入口连接到菜单栏，这样，点击菜单栏按钮时，能使用本插件功能
    :return:
    """
    window = Window
    menuBar = window.menuBar()  # 菜单栏句柄
    menu_filter = menuBar.menu_filter  # 滤镜栏句柄
    action = menuBar.newAction('颜色找查表', menuBar)  # 新建菜单栏选项
    action.func = newColorTable  # 当按钮出发时，运行 newBlur 方法
    menu_filter.addAction(action)  # 把选项添加到 滤波 分类


def newColorTable():
    global Layer
    window = Window  # 主窗体
    layer = window.currentLayer  # 获取当前图层句柄
    Layer = layer
    if layer:
        image = layer.image  # 当前图层QImage句柄
        mat = Converter.QImage2Numpy(image)  # 将QImage对象转化为numpy.array 对象
        controller = ColorLookupController(window, mat)
        controller.layer = layer
        controller.updateSlot()  # 初始更新
        if controller.exec_():
            pass


def __initColorTable():
    global ColorTable
    table = {
        0: {
            'name': '流年',
            'processor': __processor_years
        },
        1: {
            'name': '旧时光',
            'processor': __processor_oldtime
        },
    }
    ColorTable = table


def __processor_oldtime(mat):
    layer = Layer
    if not layer:
        return
    start = time.perf_counter()
    mat = mat.copy()
    data = mat[:, :, 0:3]
    # 加载R通道
    table = np.load('Plugin/ColorLookup/table/oldtime-r.npy')
    mat[:, :, 0] = LUT.D3(data, table)
    # 加载G通道
    table = np.load('Plugin/ColorLookup/table/oldtime-g.npy')
    mat[:, :, 1] = LUT.D3(data, table)
    # 加载B通道
    table = np.load('Plugin/ColorLookup/table/oldtime-b.npy')
    mat[:, :, 2] = LUT.D3(data, table)

    image = Converter.Numpy2QImage(mat)
    end = time.perf_counter()
    print('processor_oldtime', '耗时：', end - start)
    layer.updatePixmap(image)


def __processor_years(mat):
    layer = Layer
    if not layer:
        return
    start = time.perf_counter()
    mat = mat.copy()
    table = np.empty(256, np.uint8)
    for r in range(0, 256):
        v = round(math.sqrt(r) * 12)
        if v > 255:
            v = 255
        table[r] = v

    mat[..., 2] = cv2.LUT(mat[..., 2], table)
    image = Converter.Numpy2QImage(mat)
    end = time.perf_counter()
    print('processor_years', end - start)
    layer.updatePixmap(image)
